﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Deep_Talk_Converter.RenderTasks;
using Deep_Talk_Converter.Properties;
using System.Windows.Threading;
using System.Threading;
using System.IO;

namespace Deep_Talk_Converter
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ///
            /// Get paths setup for use for locating tools, etc. This is tricky
            /// as there are more than one locations for these things to be stored and
            /// also auto-discovery.
            /// 

            DTBuilderLib.ExternalToolLocations.LoadDefaultLocations();
            if (CheckDirOK(Settings.Default.DeepZoomTemplatePath))
            {
                DTBuilderLib.ExternalToolLocations.LocationSLTemplateControl = Settings.Default.DeepZoomTemplatePath;
            }
            else
            {
                Settings.Default.DeepZoomTemplatePath = DTBuilderLib.ExternalToolLocations.LocationSLTemplateControl;
            }
            if (CheckPathOK(Settings.Default.GhostscriptPath))
            {
                DTBuilderLib.ExternalToolLocations.LocationGS = Settings.Default.GhostscriptPath;
            }
            else
            {
                Settings.Default.GhostscriptPath = DTBuilderLib.ExternalToolLocations.LocationGS;
            }
        }

        /// <summary>
        /// See if there is a directory at the otehr end of this.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private bool CheckDirOK(string p)
        {
            return p != null && p != "" && Directory.Exists(p);
        }

        /// <summary>
        /// Check to see if a path is "good"
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private bool CheckPathOK(string p)
        {
            return p != null && p != "" && File.Exists(p);
        }

        /// <summary>
        /// App is up. Show the initial dude!
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShellUILoaded(object sender, RoutedEventArgs e)
        {
            MainUIShell.Children.Add(new InitialPage(this));
        }

        private RenderBase _render = null;

        /// <summary>
        /// This is the task that is going to be doing all the work.
        /// </summary>
        /// <param name="renderLocal"></param>
        internal void SetRenderTask(RenderBase renderLocal)
        {
            _render = renderLocal;
        }

        private RenderProgress _progressGUI = null;

        /// <summary>
        /// Start the actual render operation.
        /// </summary>
        internal void StartRender()
        {
            Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (ThreadStart)(() =>
            {
                Settings.Default.Save();

                MainUIShell.Children.Clear();
                _progressGUI = new RenderProgress();
                MainUIShell.Children.Add(_progressGUI);

                ///
                /// Now, hook up events for the render so we can update things!
                /// 

                _render.MeetingName += new RenderBase.MeetingNameCallback(_render_MeetingName);
                _render.Progress += new RenderBase.ProgressCallback(_render_Progress);
                _render.RenderDone += new RenderBase.RenderDoneCallback(_render_RenderDone);
                _render.Start();
            }));
        }

        /// <summary>
        /// Render is done. Move onto the last page.
        /// </summary>
        /// <param name="ok"></param>
        /// <param name="message"></param>
        void _render_RenderDone(bool ok, string message)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (ThreadStart)(() => FinishUpLastPage(ok, message)));
        }

        /// <summary>
        /// Actually do the stuff on the GUI thread.
        /// </summary>
        /// <param name="ok"></param>
        /// <param name="message"></param>
        void FinishUpLastPage(bool ok, string message)
        {
            MainUIShell.Children.Clear();
            FinalInformation fi = new FinalInformation(this);
            fi.RenderStatus.Content = message;
            if (_url != null && _url != "")
            {
                fi.urlNav.NavigateUri = new Uri(_url);
                System.Windows.Documents.Run r = (System.Windows.Documents.Run)fi.urlNav.Inlines.FirstInline;
                r.Text = _url;
            }
            MainUIShell.Children.Add(fi);
        }

        /// <summary>
        /// Update the progress.
        /// </summary>
        /// <param name="message"></param>
        void _render_Progress(string message)
        {
            _progressGUI.CurrentTask.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)(() => _progressGUI.CurrentTask.Content = message));
        }

        /// <summary>
        /// Set the meeting name here.
        /// </summary>
        /// <param name="name"></param>
        void _render_MeetingName(string name)
        {
            _progressGUI.MeetingTitle.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)(() => _progressGUI.MeetingTitle.Content = name));
        }

        string _url;

        internal void SetFinalURL(string p)
        {
            _url = p;
        }

        /// <summary>
        /// Right -- we need to show the SL stuff. Oh well!
        /// </summary>
        internal void ShowSL(RenderSL sl)
        {
            MainUIShell.Children.Clear();
            SLUploadInfo up = new SLUploadInfo(sl, this);
            MainUIShell.Children.Add(up);
        }

        /// <summary>
        /// Save the settings
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Settings.Default.Save();
        }
    }
}
